home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / answers / solar14.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  15.8 KB  |  672 lines

  1. /*
  2.  * Copyright 1996, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* solar14.c - a simple solar system.  
  19.  *    Added a reshape handler to reset the viewport and viewing volume.
  20.  *    Add depth buffering and back face culling.
  21.  *    Add a viewing transformation and control it using mouse input.
  22.  *    Enable lighting and give the sun, earth and moon material properties
  23.  *     Add continuous animation and a menu to control it.
  24.  *    Add two-sided lighting and a local light.
  25.  *    Add text.
  26.  *    Add display listed stars.
  27.  *    Add point antialiasing for the stars and a transparent "atmosphere" for
  28.  *    the earth.
  29.  *
  30.  *    F1 key            - print help information
  31.  *    Left Mouse Button    - change incidence and azimuth angles
  32.  *    Middle Mouse Button    - change the twist angle based on
  33.  *                  horizontal mouse movement
  34.  *    Right Mouse Button    - zoom in and out based on vertical
  35.  *                  mouse movement
  36.  *    <a> Key            - toggle point antialiasing on / off
  37.  *    <b> key            - cycle through different blend functions
  38.  *    <r> Key            - toggle rotation on / off
  39.  *    <R> Key            - reset viewpoint
  40.  *    SPACE Key        - toggle between solid/wireframe models
  41.  *    Escape Key        - exit program
  42.  */
  43. #include <GL/gl.h>
  44. #include <GL/glu.h>
  45. #include <GL/glut.h>
  46.  
  47. #include <stdio.h>
  48. #include <math.h>
  49.  
  50. #include "stars.h"
  51.  
  52. /* Function Prototypes */
  53.  
  54. GLvoid initgfx( GLvoid );
  55. GLvoid keyboard( GLubyte, GLint, GLint );
  56. GLvoid specialkeys( GLint, GLint, GLint );
  57. GLvoid mouse( GLint, GLint, GLint, GLint );
  58. GLvoid motion( GLint, GLint );
  59. GLvoid animate( GLvoid );
  60. GLvoid visibility( GLint );
  61. GLvoid reshape( GLsizei, GLsizei );
  62. GLvoid drawScene( GLvoid );
  63. GLvoid blendFuncCycle( GLvoid );
  64.  
  65. void checkError( char * );
  66. void printHelp( char * );
  67.  
  68. void resetView( GLvoid );
  69. void polarView( GLfloat, GLfloat, GLfloat, GLfloat);
  70.  
  71. /* Global Variables */
  72.  
  73. static char *progname; 
  74.  
  75. static GLboolean filledFlag = GL_TRUE;
  76.  
  77. static enum        actions { MOVE_EYE, TWIST_EYE, ZOOM, MOVE_NONE };
  78. static GLint        action;
  79.  
  80. static GLdouble        xStart = 0.0, yStart = 0.0;
  81.  
  82. static GLfloat        sunRadius = 0.7;
  83. static GLfloat        earthRadius = 0.4, earthOrbit = 3.5; 
  84. static GLfloat        moonRadius = 0.2, moonOrbit = 1.0;
  85. static GLfloat         near, far, distance, twistAngle, incAngle, azimAngle;
  86.  
  87. static GLfloat        year = 45.0, day = -90.0;
  88.  
  89. static void           *fixedFont, *strokeFont;
  90.  
  91. static GLuint        starlist;
  92. static GLboolean    pointSmooth = GL_TRUE;
  93.  
  94. /* Global Definitions */
  95.  
  96. #define KEY_ESC    27    /* ascii value for the escape key */
  97.  
  98. void
  99. main( int argc, char *argv[] )
  100. {
  101.     GLsizei width, height;
  102.  
  103.     glutInit( &argc, argv );
  104.  
  105.     /* create a window that is 1/4 the size of the screen,
  106.      * and position it in the middle of the screen.
  107.      */
  108.     width = glutGet( GLUT_SCREEN_WIDTH ); 
  109.     height = glutGet( GLUT_SCREEN_HEIGHT );
  110.     glutInitWindowPosition( width / 4, height / 4 );
  111.     glutInitWindowSize( width / 2, height / 2 );
  112.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
  113.     glutCreateWindow( argv[0] );
  114.  
  115.     initgfx();
  116.  
  117.     glutIdleFunc( animate );
  118.     glutVisibilityFunc( visibility );
  119.     glutReshapeFunc( reshape );
  120.     glutKeyboardFunc( keyboard );
  121.     glutSpecialFunc( specialkeys );
  122.     glutMouseFunc( mouse );
  123.     glutMotionFunc( motion );
  124.     glutDisplayFunc( drawScene ); 
  125.  
  126.     progname = argv[0];
  127.  
  128.     printHelp( progname );
  129.  
  130.     glutMainLoop();
  131. }
  132.  
  133. void
  134. printHelp( char *progname )
  135. {
  136.     fprintf(stdout, 
  137.         "\n%s - model some objects\n\n"
  138.         "F1 key        - print help information\n"
  139.         "Left Mousebutton    - move eye position\n"
  140.         "Middle Mousebutton    - change twist angle\n"
  141.         "Right Mousebutton    - move up / down to zoom in / out\n"
  142.         "<a> Key        - toggle point antialiasing on / off\n"
  143.         "<b> Key        - cycle through 3 blend functions\n"
  144.         "<r> Key        - toggle rotation on / off\n"
  145.         "<R> Key        - reset viewpoint\n"
  146.         "SPACE key    - toggle between solid/wireframe mode\n"
  147.         "Escape Key    - exit the program\n\n",
  148.         progname);
  149. }
  150.  
  151. GLvoid
  152. initgfx( GLvoid )
  153. {
  154.     GLfloat maxOrbit;
  155.  
  156.     /* Set up properties for the light */
  157.     GLfloat    sunSpecular[] = { 0.0, 0.0, 0.0, 1.0 };
  158.  
  159.     GLfloat    two_side = 1.0;
  160.  
  161.     GLfloat    lmodelAmbient[] = { 0.8, 0.8, 0.8, 1.0 };
  162.  
  163.     /* set clear color to black */
  164.     glClearColor( 0.0, 0.0, 0.0, 1.0 );
  165.  
  166.     /* enable the depth buffer */
  167.     glEnable( GL_DEPTH_TEST );
  168.  
  169.     /* Maximum size of all the objects in your scene */
  170.     maxOrbit = earthOrbit + moonOrbit + moonRadius;
  171.  
  172.     /* Set up near and far so that ( far - near ) > maxObjectSize, */
  173.     /* and determine the viewing distance (adjust for zooming) */
  174.     near = 1.0;
  175.     far = near + 8*maxOrbit; 
  176.  
  177.     resetView();
  178.  
  179.     /* Set the light properties */
  180.     glLightfv( GL_LIGHT0, GL_SPECULAR, sunSpecular );
  181.  
  182.     glLightModelf( GL_LIGHT_MODEL_TWO_SIDE, two_side );
  183.     glLightModelfv( GL_LIGHT_MODEL_AMBIENT, lmodelAmbient );
  184.  
  185.     /* Turn on the default light */
  186.     glEnable( GL_LIGHT0 );
  187.  
  188.     /* Enable fast material changes for diffuse material */
  189.     glColorMaterial( GL_FRONT, GL_DIFFUSE );
  190.  
  191.     /* Set up two fonts to use for rendering */
  192.     fixedFont = GLUT_BITMAP_9_BY_15;
  193.     strokeFont = GLUT_STROKE_ROMAN;
  194.  
  195.     init_stars();
  196.     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  197.     fprintf(stdout, 
  198.         "glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )\n" );
  199.  
  200.     starlist = glGenLists( 1 );
  201.     glNewList( starlist, GL_COMPILE );
  202.         draw_stars( distance );
  203.     glEndList();
  204. }
  205.  
  206. GLvoid 
  207. reshape( GLsizei width, GLsizei height )
  208. {
  209.     GLdouble    aspect;
  210.  
  211.     glViewport( 0, 0, width, height );
  212.  
  213.     /* compute aspect ratio */
  214.     aspect = (GLdouble) width / (GLdouble) height;
  215.  
  216.     glMatrixMode( GL_PROJECTION );
  217.  
  218.     /* Reset world coordinates first ... */
  219.     glLoadIdentity();
  220.  
  221.     /* Reset the viewing volume based on the new aspect ratio */
  222.     gluPerspective( 45.0, aspect, near, far );
  223.  
  224.     glMatrixMode( GL_MODELVIEW );
  225. }
  226.  
  227. void 
  228. checkError( char *label )
  229. {
  230.     GLenum error;
  231.     while ( (error = glGetError()) != GL_NO_ERROR )
  232.         printf( "%s: %s\n", label, gluErrorString(error) );
  233. }
  234.  
  235. GLvoid  
  236. blendFuncCycle( GLvoid )
  237. {
  238.     static int whichBlendFunc = 0;
  239.     
  240.     whichBlendFunc = (whichBlendFunc + 1) % 3;
  241.     
  242.     switch (whichBlendFunc)
  243.     {
  244.     case 0:
  245.         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  246.         fprintf(stdout, 
  247.             "glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )\n" );
  248.         break;
  249.     case 1:
  250.         glBlendFunc( GL_SRC_ALPHA, GL_ONE );
  251.         fprintf(stdout, 
  252.             "glBlendFunc( GL_SRC_ALPHA, GL_ONE )\n" );
  253.         break;
  254.     case 2:
  255.         glBlendFunc( GL_ONE, GL_ZERO );
  256.         fprintf(stdout, 
  257.             "glBlendFunc( GL_ONE, GL_ZERO )\n" );
  258.         break;
  259.     default:
  260.         break;
  261.     }
  262. }
  263.  
  264. GLvoid 
  265. keyboard( GLubyte key, GLint x, GLint y )
  266. {
  267.     static GLboolean    rotateFlag = GL_TRUE;
  268.  
  269.     switch (key) {
  270.     case 'a':
  271.         pointSmooth = !pointSmooth;
  272.         glutPostRedisplay();
  273.         break;
  274.     case 'b':    /* cycle through several blend funcs */
  275.         blendFuncCycle();
  276.         glutPostRedisplay();
  277.         break;
  278.     case 'r':
  279.         rotateFlag = !rotateFlag;
  280.         if (rotateFlag) {
  281.             glutIdleFunc( animate );
  282.         } else {
  283.             glutIdleFunc( NULL );
  284.         }
  285.         glutPostRedisplay();
  286.         break;
  287.     case ' ':    /* toggle fill mode */
  288.         filledFlag = !filledFlag;
  289.         glutPostRedisplay();
  290.         break;
  291.     case 'R':
  292.         resetView();
  293.         glutPostRedisplay();
  294.         break;
  295.     case KEY_ESC:    /* Exit when the Escape key is pressed */
  296.         exit(0);
  297.     }
  298. }
  299.  
  300. GLvoid 
  301. specialkeys( GLint key, GLint x, GLint y )
  302. {
  303.     switch (key) {
  304.     case GLUT_KEY_F1:    /* Function key #1 */
  305.         /* print help information */
  306.         printHelp( progname );
  307.         break;
  308.     }
  309. }
  310.  
  311. GLvoid 
  312. mouse( GLint button, GLint state, GLint x, GLint y )
  313. {
  314.     if (state == GLUT_DOWN) {
  315.         switch (button) {
  316.         case GLUT_LEFT_BUTTON:
  317.             action = MOVE_EYE;
  318.             break;
  319.         case GLUT_MIDDLE_BUTTON:
  320.             action = TWIST_EYE;
  321.             break;
  322.         case GLUT_RIGHT_BUTTON:
  323.             action = ZOOM;
  324.             break;
  325.         }
  326.  
  327.         /* Update the saved mouse position */
  328.         xStart = x;
  329.         yStart = y;
  330.     } else {
  331.         action = MOVE_NONE;
  332.     }
  333.  
  334. }
  335.  
  336. GLvoid
  337. motion( GLint x, GLint y )
  338. {
  339.     switch (action) {
  340.     case MOVE_EYE:
  341.         /* Adjust the eye position based on the mouse position */
  342.         azimAngle += (GLdouble) (x - xStart);
  343.         incAngle -= (GLdouble) (y - yStart);
  344.         break;
  345.     case TWIST_EYE:
  346.         /* Adjust the eye twist based on the mouse position */
  347.         twistAngle = fmodf(twistAngle+(x - xStart), 360.0);
  348.         break;
  349.     case ZOOM:
  350.         /* Adjust the eye distance based on the mouse position */
  351.         distance -= (GLdouble) (y - yStart)/10.0;
  352.         break;
  353.     default:
  354.         printf("unknown action %d\n", action);
  355.     }
  356.     
  357.     /* Update the stored mouse position for later use */
  358.     xStart = x;
  359.     yStart = y;
  360.  
  361.     glutPostRedisplay();
  362. }
  363.  
  364. GLvoid 
  365. animate( GLvoid )
  366. {
  367.     /* update the rotation of the earth and moon in their orbits */
  368.     year = fmodf( (year + 0.5), 360.0 );
  369.     day = fmodf( (day + 5.0), 360.0 );
  370.  
  371.     /* Tell GLUT to redraw the scene */
  372.     glutPostRedisplay();
  373. }
  374.  
  375. GLvoid
  376. visibility( int state ) 
  377. {
  378.     if (state == GLUT_VISIBLE) {
  379.         glutIdleFunc( animate );
  380.     } else {
  381.         glutIdleFunc( NULL );
  382.     }
  383. }
  384.  
  385. void
  386. resetView( GLvoid )
  387. {
  388.     distance = near + (far - near) / 2.0;
  389.     twistAngle = 0.0;    /* rotation of viewing volume (camera) */
  390.     incAngle = 0.0;
  391.     azimAngle = 0.0;
  392. }
  393.  
  394. void
  395. polarView( GLfloat distance, GLfloat azimuth, GLfloat incidence,
  396.             GLfloat twist)
  397. {
  398.     glTranslatef( 0.0, 0.0, -distance);
  399.     glRotatef( -twist, 0.0, 0.0, 1.0);
  400.     glRotatef( -incidence, 1.0, 0.0, 0.0);
  401.     glRotatef( -azimuth, 0.0, 0.0, 1.0);
  402. }
  403.  
  404. GLvoid
  405. renderBitmapString( void *font, char *string )
  406. {
  407.         int i;
  408.         int len = (int) strlen(string);
  409.         for (i = 0; i < len; i++) {
  410.                 glutBitmapCharacter(font, string[i]);
  411.         }
  412. }
  413.  
  414. GLvoid
  415. renderStrokeString( void *font, char *string )
  416. {
  417.         int i;
  418.         int len = (int) strlen(string);
  419.         for (i = 0; i < len; i++) {
  420.                 glutStrokeCharacter(font, string[i]);
  421.         }
  422. }
  423.  
  424. /* print mouse and keyboard input commands */
  425. GLvoid
  426. printInputCommands( void *font )
  427. {
  428.     static char *lmouse = "left mouse - change incidence & azimuth";
  429.     static char *mmouse = "middle mouse - change twist";
  430.     static char *rmouse = "right mouse - zoom in and out";
  431.     static char *Rkey = "R key - reset view";
  432.  
  433.     GLfloat yoffset;
  434.     GLsizei winHeight = glutGet(GLUT_WINDOW_HEIGHT);
  435.  
  436.     yoffset = winHeight-15.0;
  437.     glRasterPos3f( 10.0, yoffset, 0.0 );
  438.     renderBitmapString( font, lmouse );
  439.  
  440.     yoffset -= 20.0;
  441.     glRasterPos3f( 10.0, yoffset, 0.0 );
  442.     renderBitmapString( font, mmouse );
  443.  
  444.     yoffset -= 20.0;
  445.     glRasterPos3f( 10.0, yoffset, 0.0 );
  446.     renderBitmapString( font, rmouse );
  447.  
  448.     yoffset -= 20.0;
  449.     glRasterPos3f( 10.0, yoffset, 0.0 );
  450.     renderBitmapString( font, Rkey );
  451. }
  452.  
  453. /* update status of polarView parameters */
  454. GLvoid
  455. printStatus( void *font ) 
  456. {
  457.     static char s[50];
  458.     GLfloat yoffset = 65.0;
  459.  
  460.     /* update polarview information */
  461.     glRasterPos3f( 10.0, yoffset, 0.0 ); 
  462.     sprintf (s, "incidence is %4d", (GLint) incAngle);
  463.     renderBitmapString( font, s );
  464.  
  465.     yoffset -= 20.0;
  466.     glRasterPos3f( 10.0, yoffset, 0.0 );
  467.     sprintf (s, "azimuth is %4d", (GLint) azimAngle);
  468.     renderBitmapString( font, s );
  469.  
  470.     yoffset -= 20.0;
  471.     glRasterPos3f( 10.0, yoffset, 0.0 );
  472.     sprintf (s, "Twist is %4d", (GLint) twistAngle);
  473.     renderBitmapString( font, s );
  474. }
  475.  
  476. GLvoid
  477. renderStationaryText( void *font )
  478. {
  479.     GLsizei winWidth, winHeight;
  480.  
  481.     winWidth = glutGet(GLUT_WINDOW_WIDTH); 
  482.     winHeight = glutGet(GLUT_WINDOW_HEIGHT);
  483.  
  484.     /* Turn off the depth buffer */
  485.     glDisable( GL_DEPTH_TEST );
  486.  
  487.     /* save and then clear modelview matrix */
  488.     glPushMatrix(); 
  489.     glLoadIdentity(); 
  490.  
  491.     /* save Projection matrix */
  492.     glMatrixMode( GL_PROJECTION );
  493.     glPushMatrix();
  494.         /* reset world space to display status */
  495.         glLoadIdentity();
  496.         glOrtho( 0.0, winWidth, 0.0, winHeight, -1.0, 1.0 );
  497.  
  498.         printInputCommands( font );
  499.         printStatus( font );
  500.  
  501.     /* restore projection matrix */
  502.     glPopMatrix();
  503.  
  504.     /* restore previous modelview transformations */
  505.     glMatrixMode( GL_MODELVIEW );
  506.     glPopMatrix();
  507.  
  508.     /* Turn on the depth buffer */
  509.     glEnable( GL_DEPTH_TEST );
  510. }
  511.  
  512. GLvoid
  513. drawScene( GLvoid )
  514. {
  515.     static GLfloat  yellow[] = { 1.0, 1.0, 0.0, 1.0 };
  516.     static GLfloat  blue[] = { 0.0, 0.0, 1.0, 1.0 };
  517.     static GLfloat  gray[] = { 0.4, 0.4, 0.4, 1.0 };
  518.     static GLfloat  moltenRed[] = { 1.0, 0.1, 0.05, 1.0 };
  519.  
  520.     static GLfloat  smog[] = { 0.5, 0.2, 0.1, 0.2 };
  521.  
  522.     static GLfloat  noEmission[] = { 0.0, 0.0, 0.0, 1.0 };
  523.     static GLfloat  defaultDiffuse[] = { 0.8, 0.8, 0.8, 1.0 };
  524.  
  525.     /* a local light */
  526.     static GLfloat  lightPosition[] = { 0.0, 0.0, 0.0, 1.0 };
  527.  
  528.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  529.  
  530.     glPushMatrix();
  531.  
  532.         /* set up viewing transformation */
  533.         polarView( distance, azimAngle, incAngle, twistAngle );
  534.  
  535.         if (pointSmooth) {
  536.             glEnable( GL_BLEND );
  537.             glEnable( GL_POINT_SMOOTH );
  538.         }
  539.  
  540.         glCallList( starlist );
  541.  
  542.         if (pointSmooth) {
  543.             glDisable( GL_BLEND );
  544.             glDisable( GL_POINT_SMOOTH );
  545.         }
  546.  
  547.         /* use the same color for the labels as for the planets */
  548.         glColor3f( 1.0, 1.0, 0.0 );
  549.         glPushMatrix();
  550.             glTranslatef(0.0, sunRadius+0.1, 0.0);
  551.             glScalef( 0.003, 0.003, 0.003 );
  552.             renderStrokeString(strokeFont, "sun");
  553.         glPopMatrix();
  554.  
  555.         glEnable( GL_LIGHTING );
  556.         glEnable( GL_COLOR_MATERIAL );
  557.  
  558.         /* draw sun */
  559.  
  560.         /* position the light at the same location as the sun,
  561.          * so that the light emanates from it */
  562.         glLightfv( GL_LIGHT0, GL_POSITION, lightPosition );
  563.  
  564.         /* Give the sun a yellow glow */
  565.         glMaterialfv( GL_FRONT, GL_EMISSION, yellow );
  566.  
  567.         /* Set the inside of the sun to yellow */
  568.         glMaterialfv( GL_BACK, GL_AMBIENT_AND_DIFFUSE, yellow );
  569.       
  570.         glPushMatrix();
  571.             /* rotate on our own axis */
  572.             glRotatef( 90.0, 1.0, 0.0, 0.0 );
  573.             if (filledFlag)
  574.                 glutSolidSphere( sunRadius, 15, 15 );
  575.             else
  576.                 glutWireSphere( sunRadius, 15, 15 );
  577.         glPopMatrix();
  578.  
  579.         /* turn emmission off while drawing planets */
  580.         glMaterialfv( GL_FRONT, GL_EMISSION, noEmission );
  581.  
  582.         /* set diffuse material for the earth */
  583.         glColor4fv( blue );
  584.  
  585.         /* set material for the core */
  586.         glMaterialfv( GL_BACK, GL_AMBIENT_AND_DIFFUSE, moltenRed );
  587.  
  588.         glPushMatrix();
  589.  
  590.             /* draw earth */
  591.  
  592.             /* rotate to the right time of year */
  593.             glRotatef( year, 0.0, 1.0, 0.0 );
  594.  
  595.             /* translate out to our orbit about the sun */
  596.             glTranslatef( earthOrbit, 0.0, 0.0 );
  597.  
  598.             glDisable( GL_LIGHTING );
  599.             glPushMatrix();
  600.                 glTranslatef(0.0, earthRadius+0.1, 0.0);
  601.                 glRotatef(360-year, 0.0, 1.0, 0.0);
  602.                 glScalef( 0.003, 0.003, 0.003 );
  603.                 renderStrokeString(strokeFont, "earth");
  604.             glPopMatrix();
  605.             glEnable( GL_LIGHTING );
  606.  
  607.             glPushMatrix();
  608.                 /* rotate on our own axis */
  609.                 glRotatef( 90.0, 1.0, 0.0, 0.0 );
  610.                 if (filledFlag)
  611.                     glutSolidSphere( earthRadius, 15, 15 );
  612.                 else
  613.                     glutWireSphere( earthRadius, 15, 15 );
  614.  
  615.                 /* add a halo of smog around the earth */
  616.                 glEnable( GL_BLEND );
  617.                 glEnable( GL_CULL_FACE );
  618.                 glColor4fv( smog );
  619.                 glMaterialfv( GL_BACK, GL_AMBIENT_AND_DIFFUSE, smog );
  620.                 glutSolidSphere( earthRadius+0.1, 15, 15 );
  621.                 glDisable( GL_CULL_FACE );
  622.                 glDisable( GL_BLEND );
  623.             glPopMatrix();
  624.  
  625.             /* set diffuse material for the moon */
  626.             glColor4fv( gray );
  627.  
  628.             /* set material for the core of the moon */
  629.             glMaterialfv( GL_BACK, GL_AMBIENT_AND_DIFFUSE, gray );
  630.  
  631.             /* draw moon */
  632.             glPushMatrix();
  633.  
  634.                 /* rotate to the right time of day */
  635.                 glRotatef( day, 0.0, 1.0, 0.0 );
  636.  
  637.                 /* translate out to our orbit about the earth */
  638.                 glTranslatef( moonOrbit, 0.0, 0.0 );
  639.  
  640.                 glDisable( GL_LIGHTING );
  641.                 glPushMatrix();
  642.                     glTranslatef(0.0, moonRadius+0.1, 0.0);
  643.                     glRotatef(360-year-day, 0.0, 1.0, 0.0);
  644.                     glScalef( 0.003, 0.003, 0.003 );
  645.                     renderStrokeString(strokeFont, "moon");
  646.                 glPopMatrix();
  647.                 glEnable( GL_LIGHTING );
  648.  
  649.                 /* rotate on our axis */
  650.                 glRotatef( 90.0, 1.0, 0.0, 0.0 );
  651.                 if (filledFlag)
  652.                     glutSolidSphere( moonRadius, 15, 15 );
  653.                 else
  654.                     glutWireSphere( moonRadius, 15, 15 );
  655.  
  656.             glPopMatrix();
  657.  
  658.         glPopMatrix();
  659.  
  660.         glDisable( GL_COLOR_MATERIAL );
  661.         glDisable( GL_LIGHTING );
  662.  
  663.     glPopMatrix();
  664.  
  665.     glColor3f( 1.0, 1.0, 0.0 );
  666.     renderStationaryText( fixedFont );
  667.  
  668.     checkError( "drawScene" );
  669.  
  670.     glutSwapBuffers();
  671. }
  672.